﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace Chat
{
    /// <summary>
    /// Implementation for connection between one chat client and server, that
    /// uses the TCP connection.
    /// </summary>
    /// <typeparam name="OutCmd">
    /// Base class for outcomming commands, sent through the connection.
    /// </typeparam>
    public class TcpConnection<OutCmd> : Connection<OutCmd>
        where OutCmd : Command
    {
        private TcpClient Client { get; set; }

        /// <summary>
        /// Ctor for use at client side.
        /// </summary>
        /// <param name="ipEndPoint">End point at server to connect to.</param>
        public TcpConnection(IPEndPoint ipEndPoint)
        {
            Client = new TcpClient();

            Client.Connect(ipEndPoint);
        }

        /// <summary>
        /// Ctor for use at server side.
        /// </summary>
        /// <param name="client">
        /// The instanse of the TcpClient returned by TcpListener.AcceptTcpClient()
        /// </param>
        public TcpConnection(TcpClient client)
        {
            Client = client;
        }

        public override int ReceiveTimeout
        {
            get { return Client.ReceiveTimeout; }
            set { Client.ReceiveTimeout = value; }
        }

        /// <summary>
        /// Disposes the underlying TcpClient.
        /// </summary>
        public override void Close()
        {
            Client.Close();
        }

        /// <summary>
        /// The key moment of this overriden method is the TcpClient's underlying
        /// Network stream.
        /// </summary>
        /// <param name="command">The chat command to send.</param>
        /// <param name="serializer">The serializer to use for send.</param>
        public override void SendCmd(
            OutCmd command, CmdSerializer<OutCmd> serializer)
        {
            serializer.Serialize(Client.GetStream(), command);
        }

        /// <summary>
        /// The key moment of this overriden method is the TcpClient's underlying
        /// Network stream.
        /// </summary>
        /// <param name="serializer">The serializer to use for receiving the chat command.</param>
        /// <returns></returns>
        public override object ReceiveCmd(CmdSerializer<OutCmd> serializer)
        {
            return serializer.Deserialize(Client.GetStream());
        }
    }
}
